在 SvelteKit 中我們可以利用 +error.svelte
來設定遇到錯誤時該如何顯示
<!-- in src/routes/+error.svelte -->
<script lang="ts">
import { page } from '$app/stores';
</script>
<h1>status:{$page?.status}</h1>
<h1>message:{$page?.error?.message}</h1>
然後我們直接訪問一個不存在的頁面假設是 http://localhost:5173/page-not-exist
然後它也能處理在 +page.ts
以及 +layout.ts
發生的錯誤,這時先新增 src/routes/day20/+page.ts
以及 +page.svelte
// in src/routes/day20/+page.ts
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';
export const load: PageLoad = ({ params }) => {
console.log('+page.ts load', params);
error(401, 'Unauthorized');
};
<!-- in src/routes/day20/+page.svelte -->
<h1>Day 20</h1>
然後訪問 http://localhost:5173/day20
會看到以下畫面而不是如 +page.svelte
那樣的有一個 h1
的大標題。
+error.svelte
也能在每個路由(資料夾)都設定
<!-- in src/routes/day20/+error.svelte -->
<h1>Error Page in <span class="text-error">src/routes/day20/+error.svelte</span></h1>
這時再進去一次 http://localhost:5173/day20
會發現畫面變成了這樣
那如果我們再新增一個子頁面及它的 load
呢?
<!-- in src/routes/day20/foo/+page.svelte -->
<h1>day20/foo</h1>
// in src/routes/day20/foo/+page.ts
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';
export const load: PageLoad = ({ params }) => {
console.log('foo/+page.ts load', params);
error(401, 'Unauthorized');
};
沒錯畫面依然是長這樣
也就是說 +page.ts
發生錯誤時會從「自己的目錄開始找最近的 +error.svelte
來顯示,如果沒找到就往上一層找,直到找到為止」
現在來新增 +layout.ts
而且也故意讓它發生錯誤
// in src/routes/day20/+layout.ts
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';
export const load: PageLoad = ({ params }) => {
console.log('+page.ts load', params);
error(401, 'Unauthorized');
};
會發現錯誤並不是顯示 routes/day20/+error.svelte
而是變成了 routes/+error.svelte
了,這是因為 +layout.ts
它會直接「以+layout.ts
的路徑往上層開始找 +error.svelte
」
特別說明一下,是 +layout.ts
的路經的上一層開始也就是說 routes/day20/+layout.ts
發生錯誤是會找到 routes/+error.svelte
,所以就算是我訪問了routes/day20/foo/bar/baz/+page.svelte
,依然是以發生錯誤的 +layout.ts
的所在位置的上一層開始找,跟我們實際上訪問的 URL 沒太大的關係
其實 +error.svelte
就有點像是 error boundary 的概念,在處理錯誤時會在最近的 boundary 處理錯誤,所以假設發生錯誤時 +page.ts
發生錯誤時就是+page.ts
所在位置開始尋找離它最近的 boundary,而 +layout.ts
發生錯誤時就是以 +layout.ts
所在位置的上一層開始找離它最近的 boundary。
如果要直接以這份 code 來試玩的話記得把
+layout.ts
的error
註解掉才能正常顯示day20/+error.svelte
https://github.com/toddLiao469469/30days-for-svelte5/tree/main/src/routes/day20